
package com.lyyzoo.data.jdbc;

import com.google.common.collect.Lists;
import com.lyyzoo.data.domain.Page;
import com.lyyzoo.data.util.Sqls;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

public class JdbcTemplateSupport extends JdbcTemplate {
    public NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    public JdbcTemplateSupport() {
    }

    public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
        return this.namedParameterJdbcTemplate;
    }

    public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
    }

    public <T> List<T> find(String sql, Class<T> entityClass) {
        return this.query(sql, BeanPropertyRowMapper.newInstance(entityClass));
    }

    public <T> List<T> find(String sql, Class<T> entityClass, Map<String, ?> params) {
        return this.namedParameterJdbcTemplate.query(sql, params, BeanPropertyRowMapper.newInstance(entityClass));
    }

    public <T> List<T> find(String sql, Class<T> entityClass, Object... params) {
        return super.query(sql, BeanPropertyRowMapper.newInstance(entityClass), params);
    }

    public <T> List<T> find(String sql, Class<T> entityClass, int pageSize) {
        return this.find(Sqls.buildPaginateSql(sql, 1, pageSize), entityClass);
    }

    public <T> List<T> find(String sql, Class<T> entityClass, int pageSize, Map<String, ?> params) {
        return this.find(Sqls.buildPaginateSql(sql, 1, pageSize), entityClass, params);
    }

    public <T> Page<T> page(String sql, Class<T> entityClass, int pageNumber, int pageSize) {
        boolean hasCount = pageSize > 0;
        if (hasCount) {
            int count = this.queryForCount(sql);
            List<T> entities = Lists.newArrayList();
            if (count > 0) {
                entities = this.find(Sqls.buildPaginateSql(sql, pageNumber, pageSize), entityClass);
            }

            return new Page((List)entities, pageNumber - 1, pageSize, (long)count);
        } else {
            pageSize = Math.abs(pageSize);
            List<T> entities = this.find(Sqls.buildPaginateSql(sql, pageNumber, pageSize, hasCount), entityClass);
            return new Page(entities);
        }
    }

    public <T> Page<T> page(String sql, Class<T> entityClass, int pageNumber, int pageSize, Map<String, ?> params) {
        boolean hasCount = pageSize > 0;
        if (hasCount) {
            int count = this.queryForCount(sql, params);
            List<T> entities = new ArrayList();
            if (count > 0) {
                entities = this.find(Sqls.buildPaginateSql(sql, pageNumber, pageSize), entityClass, params);
            }

            return new Page((List)entities, pageNumber - 1, pageSize, (long)count);
        } else {
            pageSize = Math.abs(pageSize);
            List<T> entities = this.find(Sqls.buildPaginateSql(sql, pageNumber, pageSize, hasCount), entityClass, params);
            return new Page(entities);
        }
    }

    public <T> Page<T> page(String sql, Class<T> entityClass, int pageNumber, int pageSize, Object... params) {
        boolean hasCount = pageSize > 0;
        if (hasCount) {
            int count = this.queryForCount(sql, params);
            List<T> entities = Lists.newArrayList();
            if (count > 0) {
                entities = this.find(Sqls.buildPaginateSql(sql, pageNumber, pageSize), entityClass, params);
            }

            return new Page((List)entities, pageNumber - 1, pageSize, (long)count);
        } else {
            pageSize = Math.abs(pageSize);
            List<T> entities = this.find(Sqls.buildPaginateSql(sql, pageNumber, pageSize, hasCount), entityClass, params);
            return new Page(entities);
        }
    }

    public Integer queryForCount(String sql, Map<String, ?> params) {
        return (Integer)this.namedParameterJdbcTemplate.queryForObject(Sqls.buildCountSql(sql), params, Integer.class);
    }

    public Integer queryForCount(String sql, Object... params) {
        return (Integer)super.queryForObject(Sqls.buildCountSql(sql), params, Integer.class);
    }

    public Integer queryForCount(String sql) {
        return (Integer)super.queryForObject(Sqls.buildCountSql(sql), Integer.class);
    }
}
